<template>
  <div class="app-container">
    <el-dialog :title="dialogTitle" :destroy-on-close="true" :visible.sync="importOpen" width="75%" append-to-body :close-on-press-escape="false" :close-on-click-modal="false" :before-close="close" class="app-container-compactness">

      <upload-excel-component style="margin-bottom: 12px;" :on-success="handleSuccess" :before-upload="beforeUpload" />
      <div class="btn-box">

        <div class="btn-left">
          <el-button icon="el-icon-upload2" type="danger" :disabled="!multipleSelection.length" @click="uploadData">选中上传</el-button>
          <el-button icon="el-icon-delete" style="margin-left: 0" type="warning" :disabled="!multipleSelection.length" @click="deleteChecked">删除选中</el-button>
          <el-button icon="el-icon-milk-tea" style="margin-left: 0" type="warning" @click="clearAllSuccess">清空已成功</el-button>
        </div>
        <div class="btn-right">
          <el-button type="primary" style="margin-left: 0" icon="el-icon-plus" @click="insertEvent()">头部插入</el-button>
          <el-button type="danger" style="margin-left: 0" icon="el-icon-plus" @click="insertEvent(-1)">尾部插入</el-button>
        </div>
        <!--      <el-button @click="validAllEvent">整个表格校验</el-button>-->
      <!--      <el-button @click="fullValidEvent">校验</el-button>-->
      </div>

      <ux-grid
        ref="plxTable"
        v-loading="dialogLoading"
        element-loading-spinner="el-icon-loading"
        element-loading-background="rgba(0, 0, 0, 0.8)"
        element-loading-text="数据上传中"
        size="mini"
        border
        :show-summary="true"
        :show-overflow="'title'"
        :show-header-overflow="'title'"
        keep-source
        stripe
        :rules="rules"
        height="500"
        :edit-config="{trigger: 'click', mode: 'cell'}"
        :checkbox-config="{checkMethod: selectable, highlight: true}"
        @selection-change="handleSelectionChange"
      >
        <ux-table-column type="checkbox" width="60" />
        <ux-table-column type="index" title="行号" width="80" />

        <ux-table-column prop="name" :edit-render="{autofocus: '.el-input__inner'}" field="name" title="库位名*">
          <template v-slot:edit="scope">
            <el-input v-model="scope.row.name" />
          </template>
          <template v-slot="{ row }">{{ row.name }}</template>
        </ux-table-column>

        <ux-table-column field="isstatus" title="是否启用*" :edit-render="{autofocus: '.el-input__inner'}">
          <template v-slot:edit="scope">
            <el-select v-model="scope.row.isstatus" @change="$refs.plxTable.updateStatus(scope)">
              <el-option label="启用" value="启用" />
              <el-option label="禁用" value="禁用" />
            </el-select>
          </template>
          <template v-slot="{ row }">{{ isstatus_label( row) }}</template>
        </ux-table-column>

        <ux-table-column prop="max_load_weight" :edit-render="{autofocus: '.el-input__inner'}" field="max_load_weight" title="最大承重">
          <template v-slot:edit="scope">
            <el-input v-model="scope.row.max_load_weight" />
          </template>
          <template v-slot="{ row }">{{ row.max_load_weight }}</template>
        </ux-table-column>

        <ux-table-column prop="max_load_length" :edit-render="{autofocus: '.el-input__inner'}" field="max_load_length" title="最大长度">
          <template v-slot:edit="scope">
            <el-input v-model="scope.row.max_load_length" />
          </template>
          <template v-slot="{ row }">{{ row.max_load_length }}</template>
        </ux-table-column>

        <ux-table-column prop="max_load_width" :edit-render="{autofocus: '.el-input__inner'}" field="max_load_width" title="最大宽度">
          <template v-slot:edit="scope">
            <el-input v-model="scope.row.max_load_width" />
          </template>
          <template v-slot="{ row }">{{ row.max_load_width }}</template>
        </ux-table-column>

        <ux-table-column prop="max_load_height" :edit-render="{autofocus: '.el-input__inner'}" field="max_load_height" title="最大高度">
          <template v-slot:edit="scope">
            <el-input v-model="scope.row.max_load_height" />
          </template>
          <template v-slot="{ row }">{{ row.max_load_height }}</template>
        </ux-table-column>

        <ux-table-column
          align="center"
          width="80px"
          fixed="right"
        >
          <template slot="header" slot-scope="scope">
            <span style="color: #67C23A;">是否成功</span>
          </template>
          <template v-slot="{ row }">
            <i v-if="row.isUpload === 1" class="el-icon-success" style="color: #67C23A" />
            <el-tooltip v-else-if="row.isUpload === 0" class="item" effect="dark" :content="row.errMsg" placement="top">
              <i class="el-icon-error" style="color: #F56C6C" />
            </el-tooltip>
            <span v-else />
          </template>
        </ux-table-column>

      <!--      <ux-table-column-->
      <!--        title="操作"-->
      <!--        width="200"-->
      <!--        fixed="right"-->
      <!--      >-->
      <!--        <template v-slot="{ row }">-->
      <!--          &lt;!&ndash;判断行是否激活了, 编辑按钮执行的方式就是为了去激活&ndash;&gt;-->
      <!--          <template v-if="$refs.plxTable.isActiveByRow(row)">-->
      <!--            <el-button type="primary" @click="saveEvent(row)">保存</el-button>-->
      <!--            <el-button @click="cancelRowEvent(row)">取消</el-button>-->
      <!--          </template>-->
      <!--          <template v-else>-->
      <!--            <el-button @click="editRowEvent(row)">编辑</el-button>-->
      <!--          </template>-->
      <!--        </template>-->
      <!--      </ux-table-column>-->
      </ux-grid>
    </el-dialog>
  </div>
</template>

<script>
import UploadExcelComponent from '@/components/UploadExcel/index.vue'
import { getProject } from '@/api/storehouse'
import { providerList } from '@/api/basics'
import { att, locationBatchCreate } from '@/api/stock'
export default {
  name: 'WarehouseConfigImport',
  components: { UploadExcelComponent },
  props: {
    importOpen: {
      type: Boolean,
      default: false
    },
    dialogTitle: {
      type: String,
      default: ''
    },
    confidId: {
      type: [String, Number],
      default: ''
    }
  },
  data() {
    const projectClientRules = ({ cellValue, rule }) => {
      if (!Array.isArray(cellValue) || cellValue.length != 2) {
        return new Error('请选择项目和委托方')
      }
    }
    return {
      dialogLoading: false,
      clientParams: {
        page: 1,
        limit: 9999,
        account_code: undefined,
        account_name: undefined
      },
      clientList: [],
      selectList: [],
      multipleSelection: [],
      err_xid_arr: [],
      selectData: [],
      tableKeyMap: {
        '库位名*': 'name',
        '是否启用*': 'isstatus',
        '最大承重': 'max_load_weight',
        '最大长度': 'max_load_length',
        '最大宽度': 'max_load_width',
        '最大高度': 'max_load_height'
      },
      rules: {
        name: [
          // { required: true, validator: projectClientRules, message: '请选择项目和委托方' }
          { required: true, message: '请填写库位名' }
        ],
        isstatus: [
          { required: true, message: '请选择是否启用' }
        ]
      },
      tableHeader: [],
      tableData: [],
      columns: []
    }
  },
  computed: {

  },
  created() {
    this.project()
  },
  mounted() {
    this.getClientList()
  },
  methods: {
    clearAllSuccess() {
      this.tableData = this.tableData.filter(item => item.isUpload !== 1)
      this.$refs.plxTable.loadData(this.tableData)
    },
    selectable({ row }) {
      return row.disabled !== 'disabled'
    },
    // 添加插入行
    insertEvent(row) {
      if (row === -1) {
        this.tableData.push({})
      } else {
        this.tableData.unshift({})
      }
      this.$refs.plxTable.loadData(this.tableData)
      // this.$refs.plxTable.reloadData(this.tableData)
    },
    // 删除选中行
    deleteChecked() {
      this.$refs.plxTable.removeCheckboxRow()
      const xids = this.multipleSelection.map(item => item._XID)
      this.tableData = this.tableData.filter(item => !xids.includes(item._XID))
      this.$refs.plxTable.loadData(this.tableData)
      // this.$refs.plxTable.reloadData(this.tableData)
      this.multipleSelection = []
    },
    close() {
      this.tableData = []
      this.multipleSelection = []
      this.$emit('update:importOpen', false)
    },
    getClientList() {
      providerList(this.clientParams).then(response => {
        if (response.code === 10000) {
          this.clientList = response.data
        }
      })
      att().then((response) => {
        if (response.code === 10000) {
          this.selectList = JSON.parse(JSON.stringify(response.data))
        }
      })
    },

    handleSelectionChange(val) {
      this.multipleSelection = val
    },
    async processBatch(startIndex, batchSize) {
      // 计算结束索引
      const endIndex = Math.min(startIndex + batchSize, this.multipleSelection.length)

      const requestData = this.multipleSelection.slice(startIndex, endIndex)
      const requestDataXIDs = requestData.map(item => item._XID)

      requestData.forEach(item => {
        item.isstatus = item.isstatus === '启用' ? 1 : 0
        item.parent_id = this.confidId
      })

      const { data: errArr } = await locationBatchCreate({ list: requestData })
      const errArrKeys = Object.keys(errArr)

      if (errArrKeys) {
        this.tableData.forEach(item => {
          if (requestDataXIDs.includes(item._XID)) {
            if (errArrKeys.includes(item._XID)) {
              item.isUpload = 0
              item.errMsg = errArr[item._XID].errMsg
            } else {
              item.isUpload = 1
              item.disabled = 'disabled'
            }
          }
        })

        this.err_xid_arr = this.err_xid_arr.concat(errArrKeys)
      }

      // 检查是否还有剩余数据需要处理
      if (endIndex < this.multipleSelection.length) {
        // 使用延迟执行来等待一段时间后继续处理下一批数据'
        await new Promise(resolve => setTimeout(resolve, 100))
        await this.processBatch(endIndex, batchSize)
      } else {
        this.multipleSelection = this.multipleSelection.filter(item => this.err_xid_arr.includes(item._XID))
        this.$refs.plxTable.clearSelection()
      }
    },
    async uploadData() {
      this.err_xid_arr = []
      const data = await this.$refs.plxTable.validate(this.multipleSelection)

      if (data) { // 失败
        let masStr = ''
        Object.values(data).forEach(errList => {
          errList.forEach(params => {
            const { rowIndex, column, rules } = params
            rules.forEach(rule => {
              masStr += `<p>第 ${rowIndex + 1} 行 ：${rule.message}</p>`
            })
          })
        })
        // 我用的提示是element-ui的，不要说你没安装element，就说为啥报错
        return this.$notify.error({
          title: '错误',
          dangerouslyUseHTMLString: true,
          message: masStr,
          duration: 3500
        })
      }
      // console.log(this.multipleSelection)
      // console.log(this.$refs.plxTable.getRowById('row_15'))
      // 调用接口
      this.dialogLoading = true
      await this.processBatch(0, 5)
      if (this.err_xid_arr.length) {
        this.$notify.error({
          title: '错误',
          message: `有${this.err_xid_arr.length}个错误`
        })
      } else {
        this.$notify({
          type: 'success',
          title: 'Ok',
          duration: 3500
        })
      }
      this.dialogLoading = false
      // const errArr = ['row_15', 'row_14']
    },
    // 校验
    fullValidEvent() {
      // fullValidate完整校验，和 validate 的区别就是会给每一行进行校验
      this.$refs.plxTable.fullValidate().then(data => {
        // data就是当前检验不通过的
        if (data) {
          let masStr = ''
          Object.values(data).forEach(errList => {
            console.log(errList)
            errList.forEach(params => {
              const { rowIndex, column, rules } = params
              rules.forEach(rule => {
                masStr += `<p>第 ${rowIndex} 行 ${column.title} 校验错误：${rule.message}</p>`
              })
            })
          })
          // 我用的提示是element-ui的，不要说你没安装element，就说为啥报错
          this.$notify.error({
            title: '错误',
            dangerouslyUseHTMLString: true,
            message: masStr,
            duration: 1500
          })
        } else {
          // 我用的提示是element-ui的，不要说你没安装element，就说为啥报错
          this.$message({
            message: '校验成功',
            type: 'success',
            duration: 1500
          })
        }
      })
    },
    // 整个表格校验
    validAllEvent() {
      // 1. validate方法 如果你传入一个true， 那么就代表整个表格校验！
      // 2.快速校验，如果存在校验不通过的行，则返回不再继续校验
      this.$refs.plxTable.validate(true).then(data => {
        if (data) {
          this.$message({
            message: '校验不通过',
            type: 'error',
            duration: '1000'
          })
        } else {
          this.$message({
            message: '校验成功',
            type: 'success',
            duration: '1000'
          })
        }
      })
    },
    editRowEvent(row) {
      this.$refs.plxTable.setActiveRow(row)
    },
    consignee_label(row) {
      let label = ''
      this.clientList.forEach(item => {
        if (item.serial_number == row.consignee_serial_number) {
          label = item.account_name
        }
      })
      return label
    },
    isstatus_label(row) {
      const label = ''
      if (row.isstatus == 1 || row.isstatus == '启用') {
        return '启用'
      } else if (row.isstatus == 0 || row.isstatus == '禁用') {
        return '禁用'
      }

      return label
    },
    project_client_label(row) {
      let label = ''
      this.selectData.forEach(item => {
        if (Array.isArray(row.project_client) && item.value == row.project_client[0]) {
          item.children.forEach(itm => {
            if (itm.value == row.project_client[1]) {
              label = item.label + '/' + itm.label
              return
            }
          })
        }
      })
      return label
    },
    project() {
      const that = this
      getProject().then(response => {
        if (response.code === 10000) {
          that.selectData = response.data
        }
      })
    },
    // 点击保存
    saveEvent(row) {
      // 判断是否发生改变
      console.log(this.$refs.plxTable.isUpdateByRow(row))
      if (this.$refs.plxTable.isUpdateByRow(row)) {
        // 局部保存，并将行数据恢复到初始状态（如果 第二个参数record 为空则不改动行数据，只恢复状态）
        // 必须执行这个，不然下次点击保存，还是保存成功哦！状态没改变哦
        this.$refs.plxTable.reloadRow(row, null, null)
        // ...保存逻辑相关（后端呀，或者前端呀）
        this.$message({
          message: '恭喜你，保存成功',
          type: 'success'
        })
      } else {
        this.$message({
          message: '保存失败，你没改变当前行的数据',
          type: 'error'
        })
      }
    },
    // 转换男女
    getLabel(val) {
      const item = this.sexList.filter(item => item['value'] === val)[0]
      return item ? item.label : ''
    },
    // 转换地址
    getCascader(value, list) {
      const values = value || []
      const labels = []
      const cascaderData = function(index, list) {
        const val = values[index]
        if (list && values.length > index) {
          list.forEach(item => {
            if (item.value === val) {
              labels.push(item.label)
              cascaderData(++index, item.children)
            }
          })
        }
      }
      cascaderData(0, list)
      return labels.join(' / ')
    },
    beforeUpload(file) {
      const isLt1M = file.size / 1024 / 1024 < 1

      if (isLt1M) {
        return true
      }

      this.$message({
        message: 'Please do not upload files larger than 1m in size.',
        type: 'warning'
      })
      return false
    },
    handleSuccess({ results, header }) {
      this.multipleSelection = []
      this.tableData = results
      const that = this

      const newData = this.tableData.map(item => {
        const newItem = {}
        for (const key in item) {
          if (Object.prototype.hasOwnProperty.call(that.tableKeyMap, key)) {
            newItem[that.tableKeyMap[key] || key] = item[key]
          }
        }
        return newItem
      })
      this.tableData = newData

      this.tableData.forEach(item => {
        // 是否启用
        if (item.isstatus) {
          if (item.isstatus == '启用' || item.isstatus == 1) {
            item.isstatus = '启用'
          }
        }
      })

      this.tableHeader = header
      this.$refs.plxTable.reloadData(this.tableData)
    }
  }
}
</script>
<style lang="less" scoped>
.btn-box{
  display: flex;
  justify-content: space-between;
}
</style>
